﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Persian_Subtitle_Encoding_Fixer
{
    public partial class Form1 : Form
    {
        private String _filePath;
        private byte[] _fileContent;
        // -----------------------------
        private String[] _encodings;
        private int _encodingIndex;
        // -----------------------------
        private String[] _messages;
        private String _failureMessage;
        // -----------------------------
        private Encoding _selectedEncoding;
        // -----------------------------
        private int _maxFormHeight = 560;
        private int _minFormHeight = 218;

        public Form1()
        {
            InitializeComponent();

            picTopIcon.BackColor = Color.Transparent;
            pnlDragAndDrop.BackColor = Color.FromArgb(114, 177, 245);

            this.Height = this._minFormHeight;

            // Encodings which Iranian use for their subtitle
            this._encodings = new String[]{
                "windows-1256",
                "utf-8",
                "x-mac-arabic",
                "utf-7",
                "utf-32",
                "unicodeFFFE",
                "iso-8859-6",                
                "utf-32BE",
                "us-ascii",                
                "DOS-720",
                "DOS-862"                
            };

            // Messages that will show to user for each encoding
            this._messages = new String[] { 
                "الان می‌شه درست دید؟",
                "الان چی؟",
                "درست شد؟",
                "باید درست شده باشه دیگه؟",
                "درسته نه؟",
                "به نظر باید درسته شده باشه، آره؟"
            };


            // Define failure message
            this._failureMessage = "امیدی به رفع مشکل این زیرنویس نیست، من شرمندم!";

            // Define the default encoding
            this._encodingIndex = 0;
        }


        private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Title = "لطفاً فایل زیرنویس خود را انتخاب کنید.";
            openFileDlg.Filter = "SRT زیرنویس‌های|*.srt|SSA زیرنویس‌های|*.ssa|ASS زیرنویس‌های|*.ass|(هر نوع فایلی)|*.*";


            if (openFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                ReadSubtitle(openFileDlg.FileName);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        internal void ReadSubtitle(String filename)
        {
            // Set subtitle path
            this._filePath = filename;


            // Read subtitle content
            try
            {
                this._fileContent = File.ReadAllBytes(this._filePath);
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("اجازه دسترسی به فایل رو ندارم!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);

                return;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("فایل پیدا نشد،\r\nبهتر بگم وجود خارجی نداره!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }
            catch
            {
                MessageBox.Show("متاسفانه خطایی ناشناخته رخ داد.", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }

            // Get File name
            FileInfo fileInfo = new FileInfo(this._filePath);
            //lblSelectedFileName.Text = fileInfo.Name;
            groupBox3.Text = fileInfo.Name;

            // Show preview
            this.Preview();
            // make form longer and show other options
            MakeFormLonger();
            return;
        }


        /// <summary>
        /// Convert subtitle text into selected encoding
        /// </summary>
        private void Preview()
        {
            // Get selected encoding
            this._selectedEncoding = Encoding.GetEncoding(this._encodings[this._encodingIndex]);

            // Convert text into selecected encoding
            String subtitle = this._selectedEncoding.GetString(this._fileContent);

            // Tries to find a new line to make a preview of subtitle
            try
            {
                int indexOfNewLine = subtitle.IndexOf("\n", 1024);
                if (indexOfNewLine > 0)
                    subtitle = subtitle.Substring(0, indexOfNewLine);
            }
            catch{}

            // Show preview
            previewRichTextBox.Text = subtitle;

        }

        /// <summary>
        /// Get next encoding and show the preivew
        /// </summary>
        /// <returns></returns>
        private Boolean NextEncoding()
        {
            if (this._encodingIndex < this._encodings.Length - 1)
            {
                ++this._encodingIndex;
                this.Preview();
                return true;
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        private void MakeFormLonger()
        {
            this._encodingIndex = 0;

            if (this.Height != this._maxFormHeight)
            {
                this.Height = this._maxFormHeight;
                //int newTop = this.Top - (this._maxFormHeight / 2) + 50;
                //this.Top = newTop;
                this.CenterToScreen();
            }
            
            pictureBox2.Enabled = true;
            pictureBox3.Enabled = true;
            btnYes.Enabled = true;
            btnNo.Enabled = true;
            previewRichTextBox.Enabled = true;
        }

        private void btnNo_Click(object sender, EventArgs e)
        {

            if (NextEncoding())
            {
                Random rnd = new Random();
                lblQuestion.Text = this._messages[rnd.Next(0, this._messages.Length - 1)];
            }
            else
            {
                lblQuestion.Text = this._failureMessage;
                btnYes.Enabled = false;
                btnNo.Enabled = false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void Save()
        {
            try
            {
                File.WriteAllBytes(this._filePath, Encoding.Convert(this._selectedEncoding, UTF8Encoding.UTF8, this._fileContent));
                // -------------------------------------
                MessageBox.Show("با یونیکد UTF-8 ذخیره شد.", "انجام شد", MessageBoxButtons.OK, MessageBoxIcon.Information,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);                
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("اجازه دسترسی به فایل رو ندارم!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);

                return;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("فایل پیدا نشد،\r\nبهتر بگم وجود خارجی نداره!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }
            catch
            {
                MessageBox.Show("متاسفانه خطایی ناشناخته رخ داد.", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void SaveAs()
        {
            try
            {
                FileInfo fileInfo = new FileInfo(this._filePath);

                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = String.Format("(*.{0} Files)*.{0}", fileInfo.Extension);

                if(saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {

                    File.WriteAllBytes(saveFileDialog.FileName, Encoding.Convert(this._selectedEncoding, UTF8Encoding.UTF8, this._fileContent));
                    // -------------------------------------
                    MessageBox.Show("با یونیکد UTF-8 ذخیره شد.", "انجام شد", MessageBoxButtons.OK, MessageBoxIcon.Information,
                        MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);           
                }
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("اجازه دسترسی به فایل رو ندارم!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);

                return;
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("فایل پیدا نشد،\r\nبهتر بگم وجود خارجی نداره!", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }
            catch
            {
                MessageBox.Show("متاسفانه خطایی ناشناخته رخ داد.", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign);
                return;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnYes_Click(object sender, EventArgs e)
        {
            DialogResult whatShouldIdo = MessageBox.Show("آیا فایل را جایگزین فایل قبلی نمایم؟", "نیاز به تصمیم گیری شما دارم", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, 
                MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);

            if (whatShouldIdo == System.Windows.Forms.DialogResult.Yes)
                this.Save();
            else if (whatShouldIdo == System.Windows.Forms.DialogResult.No)
                this.SaveAs();
        }

        private void pnlDragAndDrop_DragDrop(object sender, DragEventArgs e)
        {
            string[] s = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            pnlDragAndDrop.BackColor = Color.FromArgb(114, 177, 245);
            ReadSubtitle(s[0]);
        }

        private void pnlDragAndDrop_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
                pnlDragAndDrop.BackColor = Color.FromArgb(0, 122, 204);
            }
            else
                e.Effect = DragDropEffects.None;
        }

        private void pnlDragAndDrop_DragLeave(object sender, EventArgs e)
        {
            pnlDragAndDrop.BackColor = Color.FromArgb(114, 177, 245);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void lblAbout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            AboutBoxDialog aboutDialog = new AboutBoxDialog();
            aboutDialog.ShowDialog();
        }



    }
}
